package cn.keniykey.mc.viewlibrary.reflection;

import java.lang.reflect.Field;
import java.util.LinkedList;
import java.util.logging.Logger;

import javax.annotation.Nullable;

import cn.keniykey.mc.viewlibrary.ViewLibraryMain;

public final class ReflectionField{
    private Field field;
 
    public ReflectionField(final Field field) {
    	this.field = field;
    	this.field.setAccessible(true);
    }
    
    public Field getField() {
        return this.field;
    }
	public Class<?> getNBTClass() {
    	return this.field.getDeclaringClass();
    }
	public Class<?> getFieldClass() {
		return this.field.getType();
    }
    public ReflectionDynamicField getDynamicField(final Object obj) {
        return new ReflectionDynamicField(this.field, obj);
    }
    @Nullable
    public Object dynamicGet(final Object obj) {
    	try {
			return this.field.get(obj);
		}catch (Exception ex) {
			throw new RuntimeException(ex);
		}
    }
    public void dynamicSet(final Object obj,@Nullable Object anything) {
    	try {
			this.field.set(obj, anything);
		}catch (Exception ex) {
			throw new RuntimeException(ex);
		}
    }
    @Nullable
    public Object get() {
    	try {
			return this.field.get(null);
		}catch (Exception ex) {
			throw new RuntimeException(ex);
		}
    }
    public void set(@Nullable Object anything) {
    	try {
			this.field.set(null, anything);
		}catch (Exception ex) {
			throw new RuntimeException(ex);
		}
    }
    
	public void showLogger() {
		final Logger logger = ViewLibraryMain.getPlugin().getLogger();
		logger.warning("---------------" + this.field.getName() + "--------------------");
		final StringBuilder strb = new StringBuilder("class: ");
		final Object obj_par = ReflectionGenericClass.getParameterClasses(this.field.getGenericType());
		if(obj_par instanceof Class) {
			strb.append("[Class]");
			final Class<?> clazz_par = (Class<?>)obj_par;
			strb.append(clazz_par.getName());
		}else if(obj_par instanceof LinkedList) {
			strb.append("[LinkedList]");
			@SuppressWarnings("unchecked")
			final LinkedList<Class<?>> linke_clazz_par = (LinkedList<Class<?>>) obj_par;
			strb.append("<C>");
			strb.append(linke_clazz_par.removeFirst().getName());
			for(Class<?> linked_clazz : linke_clazz_par) {
				strb.append(", [G]").append(linked_clazz.getName());
			}
		}
		logger.warning(strb.toString());
		logger.warning("------------------end-------------------------");
	}
}